package net.area80.components
{
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import net.area80.components.skin.ABScrollbarSkin;
	import net.area80.utils.DrawingUtils;
	
	import org.osflash.signals.Signal;
	
	
	public class UIVScrollSwapList extends Sprite
	{
		private var listHeight:uint;
		private var listWidth:uint;
		
		private var swapItem:Boolean = false;
		private var mouseNavigation:Boolean = false;
		private var separator:Sprite = null;
		private var scroll:VScrollbar;
		private var skin:ABScrollbarSkin;
		private var masking:Sprite;
		private var container:Sprite;
		private var itemList:Vector.<UIListItem>;
		
		public var SIGNAL_REARRANGE:Signal = new Signal(UIVScrollSwapList);
		
		public function UIVScrollSwapList(listHeight:uint, listWidth:uint, skin:ABScrollbarSkin, swapItem:Boolean=false,mouseNavigation:Boolean=false, separator:Sprite=null)
		{
			super();
			
			this.listHeight = listHeight;
			this.listWidth = listWidth;
			this.skin = skin;
			this.swapItem = swapItem;
			this.mouseNavigation = mouseNavigation;
			this.separator = separator;
			this.skin = skin;
			
			container = new Sprite();
			addChild(container);
			
			scroll = new VScrollbar(skin,container,listHeight,1);
			addChild(scroll);
			scroll.x = listWidth;
			scroll.height = listHeight;
			
			if(!separator) {
				this.separator = new Sprite();
				this.separator.addChild(DrawingUtils.getRectSprite(listWidth,4,0x000000,0,-2));
			}
			
			container.cacheAsBitmap = true;
			masking = DrawingUtils.getRectSprite(listWidth,listHeight);
			masking.cacheAsBitmap = true;
			addChild(masking);
			container.mask = masking;
			
			addEventListener(Event.REMOVED_FROM_STAGE, dispose);
			
			addEventListener(Event.ENTER_FRAME, positionUpdate);
			
			if(swapItem) {
				container.addChild(this.separator);
				this.separator.visible = false;
			}
			
		
		}
		public function get scrollbar ():VScrollbar {
			return scroll;
		}
		private function dispose (e:Event):void {
			removeEventListener(Event.ENTER_FRAME, positionUpdate);
			stage.removeEventListener(MouseEvent.MOUSE_UP, dragCompleted);
			removeEventListener(Event.ENTER_FRAME, updateMouseDrag);
			if(currentDragBmp) currentDragBmp.bitmapData.dispose();
		}
		public function get length ():uint {
			return (itemList) ? itemList.length : 0;
		}
		public function getItemAt (id:uint):UIListItem {
			return (itemList) ?  itemList[id] : null;
		}
		public function getItemList ():Vector.<UIListItem> {
			return itemList;
		}
		public function addItem (u:UIListItem):void {
			if(!itemList) itemList = new Vector.<UIListItem>;
			u.init(this);
			//u["setID"](itemList.length);
			if(swapItem) u.SIGNAL_MOUSE_DOWN.add(itemMouseDownHandler);
			u.cacheAsBitmap = true;
			container.addChild(u);
			itemList.push(u);
			
		}
		private function positionItem ():void {
			var cH:Number = 0;
			if(itemList) {
				for(var i:uint =0;i<itemList.length;i++) {
					if(itemList[i].visible) {
						//itemList[i].y += (cH-itemList[i].y)*0.2;
						itemList[i].y = cH;
						cH += itemList[i].height;
					}
					
				}
			}
			scroll.updateDisplay();
			
		}
		private function positionUpdate (e:Event):void {
			positionItem();
	
		}
		private var currentDragItem:UIListItem;
		private var currentDragBmp:Bitmap;
		private var downPosition:Point;
		private function itemMouseDownHandler (u:UIListItem):void {

			downPosition = new Point(u.mouseX,u.mouseY);
			currentDragItem = itemList.splice(itemList.indexOf(u),1)[0];
			currentDragItem.visible = false;
			if(currentDragBmp) currentDragBmp.bitmapData.dispose();
			currentDragBmp = new Bitmap(u.getSnapshot());
			currentDragBmp.alpha = .5;
			addEventListener(Event.ENTER_FRAME, updateMouseDrag);
			separator.visible = true;
			stage.addChild(currentDragBmp);
			stage.addEventListener(MouseEvent.MOUSE_UP, dragCompleted);
			positionItem();
		}
		private function getCurrentDragID ():int {
			for(var i:uint =0;i<itemList.length;i++) {
				if(itemList[i]==currentDragItem) {
					return i;
				}
			}
			return -1;
		}
		private function dragCompleted (e:MouseEvent):void {
			

			
			currentDragItem.visible = true;
			//if(itemList.length>1) {
				
				var newPos:Number = saparatorID();
				var newItemList:Vector.<UIListItem> = new Vector.<UIListItem>;
				var finding:Boolean = true;
				var newlen:uint = itemList.length+1;
				while (newItemList.length<newlen) {
					if(newItemList.length==newPos) {
						newItemList.push(currentDragItem);
						if(newItemList.length>1&&newItemList[newItemList.length-2]) {
							currentDragItem.y = newItemList[newItemList.length-2].y + newItemList[newItemList.length-2].height;
						} else {
							currentDragItem.y = 0;
						}
						
						currentDragItem = null;
					}
					if(itemList.length>0) {
						newItemList.push(itemList.shift());
					} else {
						if(currentDragItem) {
							newItemList.push(currentDragItem);
							if(newItemList.length>1&&newItemList[newItemList.length-2]) {
								currentDragItem.y = newItemList[newItemList.length-2].y + newItemList[newItemList.length-2].height;
							} else {
								currentDragItem.y = 0;
							}
							currentDragItem = null;
						}
					}
				}
				itemList = newItemList;
			//}
			stage.removeEventListener(MouseEvent.MOUSE_UP, dragCompleted);
			removeEventListener(Event.ENTER_FRAME, updateMouseDrag);
			stage.removeChild(currentDragBmp);
			currentDragBmp.bitmapData.dispose();
			
			currentDragItem = null;
			separator.visible = false;
			SIGNAL_REARRANGE.dispatch(this);
			positionItem();
		}
		private function saparatorID ():int {
			var id:int = 0;
			for(var i:uint =0;i<itemList.length;i++) {
				if(container.mouseY<=itemList[i].y-itemList[i].height*0.5) {
					break;
				} else {
					id = i;
					if(i==itemList.length-1) {
						//TODO: aaa
						if(container.mouseY>itemList[i].y+itemList[i].height*0.5) {
							id = i+1;
						}
					}
				}
				
			}
			return id;
		}
		private function updateMouseDrag (e:Event):void {
			var r:Number = mouseY-listHeight*.5
			scroll.ratio += r*0.001*(listHeight/container.height);
			currentDragBmp.x = currentDragItem.localToGlobal(new Point(currentDragItem.x,0)).x;
			currentDragBmp.y = stage.mouseY-downPosition.y;
			var sepid:int = saparatorID();
			if(sepid==itemList.length) {
				separator.y = itemList[itemList.length-1].y+itemList[itemList.length-1].height;
			} else {
				separator.y = itemList[saparatorID()].y;
			}
		}
		
	}
}